<?php

use app\modules\Admin\models\membermoneylogModel;
use app\service\goods;
use Illuminate\Database\Capsule\Manager as DB;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Style\Color;
use Illuminate\Support\Carbon;

#[测试控制器]
class TestController extends CommonController
{
    protected $authExcept = ['index', 'testQueueJob', 'zhujie', 'contrans', 'lock',
        'memberChildren', 'applylog', 'agentGoods', 'reCalcTotalconsume',
        'reCalcTeamconsume', 'exportorder', 'autoReceiveQueue', 'manualsettle',
        'addAutoReceiveQueue', 'addHistoryAutoReceiveQueue', 'uploadCdn', 'teamChildLine',
        'expressnoflush', 'manualsettlereward', 'carbon', 'manualpatchorder'];

    #[carbonTest]
    public function carbonAction()
    {
//        $date = carbon(timestamp(1655286291));
//        $date_add = carbon($date)->addSeconds(186400);
//        $now = carbon();
//        if($date_add->lt($now)) {
//            echo "{$date_add->format('Y-m-d H:i:s')} 比 {$now->format('Y-m-d H:i:s')} 小";
//        }else{
//            echo "{$date_add->format('Y-m-d H:i:s')} 比 {$now->format('Y-m-d H:i:s')} 大";
//        }
//        echo controllerFile('Dianpu_Category', 'Admin');
    }
    #[首页]
    public function indexAction()
    {
        $avatar = 'http://thirdwx.qlogo.cn/mmopen/ajNVdqHZLLDMmjrupXHmeJaPibSZhic2NgGgOXQWxLqXmQPUMtdEY6wtOOfBsk8JCXJPrV9Ds6sYib4Fy1R6zOPLNJpgT2RPhcftyRoRuSAL68/132';
        file_put_contents('D:/webroot/uushop/api/public/excel/abc.gif',
            request($avatar));

        $avatarImg = imagecreatefromstring(request($avatar));
        $bgHight = ImageSX($avatarImg);
        $bgWidth = ImageSY($avatarImg);

        echo $bgWidth, PHP_EOL;
        echo $bgHight, PHP_EOL;

        echo 'Done';
        exit;


        #$tuiker = \tuikeModel::where('tuike_id', 123)->first();
        $tuiker = \tuikeModel::find(1391232)->toArray();
        if (!$tuiker) {
            echo 'WOW';
        }
        dump($tuiker);
        exit;

        $order = orderModel::find(126790);
        $items = $order->item;
        $items = array_column($items->toArray(), null, 'id');
        dump($items);
        exit;

        $members = \memberchildrenModel::where('children_id', 99)->orderBy('level', 'asc')->pluck('member_id');
        $members->prepend(99);
        dump($members->toArray());
        exit;

        $zhituiRules = \tuikelevelModel::select('level', 'award_zhitui as ratio')->get()->toArray();
        $jiantuiRules = \tuikelevelModel::select('level', 'award_jiantui as ratio')->get()->toArray();
        dump($zhituiRules);
        dump($jiantuiRules);
        exit;

        $parents = memberchildrenModel::where('children_id', 1186023)->pluck('member_id', 'level');
        foreach ($parents as $level => $parent) {
            echo $level, ':', $parent, PHP_EOL;
        }
        exit;

        $counter = DB::select('SELECT count(*) as cnt from cs_member where level>1 and id in (SELECT children_id from cs_member_children where level=1 and `member_id`=:id) ', ['id' => 1924]);
        dump($counter[0]->cnt);
        exit;

        $goods = goodsModel::first();
        Hook::emit('order_create_before', ['a' => 1, 'b' => 2, 'c' => $goods->id, 'd' => $goods->title]);
        Hook::emit('order_create_after', ['a' => 1, 'b' => 2, 'c' => $goods->id, 'd' => $goods->title]);
        json(['ret' => 0, 'msg' => 'welcome to uushop.com', 'data' => goods::list()]);
    }

    #[测试队列任务]
    public function testQueueJobAction()
    {
        Queue::push('app\job\order@payed', [
            'order_sn' => '12345',
            'trand_no' => '12312345151',
            'notification' => 'notification'
        ], 'shop');

        (new Queue)->push('app\job\order@payed', [
            'order_sn' => '54321',
            'trand_no' => '12312345151',
            'notification' => 'notification'
        ], 'shop');

        echo 'done';
    }

    #[测试注解]
    public function zhujieAction()
    {
        $reflector = new ReflectionClass(self::class);
        $value = strtolower(substr(self::class, 0, -10));
        if ($reflector->getAttributes()) {
            $class = $reflector->getAttributes()[0]->getName();
        } else {
            $class = $value;
        }
        dump(['id' => $value, 'text' => $class]);

        foreach ($reflector->getMethods(ReflectionMethod::IS_PUBLIC) as $k => $v) {
            if (substr($v->name, -6) === 'Action') {
                $value = strtolower(substr($v->name, 0, -6));
                if ($v->getAttributes()) {
                    $name = $v->getAttributes()[0]->getName();
                } else {
                    $name = $value;
                }
                dump(['id' => $value, 'text' => $name]);
            }
        }
    }

    #[测试并发事务]
    public function contransAction()
    {
        try {
            $money = 10;
            DB::beginTransaction();
            $from = memberModel::where('id', 236)->first();
            $to = memberModel::where('id', 237)->first();
            echo 'before, ', $from->money, ':', $to->money, PHP_EOL;
            if ($from->money >= $money) {
                $from->money = DB::raw('money - ' . $money);
                $to->money = DB::raw('money + ' . $money);
            } else {
                throw new Exception('余额不足');
            }
            sleep(10);
            $from->save();
            $to->save();
            DB::commit();
            $from = memberModel::where('id', 236)->first();
            $to = memberModel::where('id', 237)->first();
            echo 'after, ', $from->money, ':', $to->money, PHP_EOL;
            $result = array(
                'code' => '200',
                'msg' => '操作成功',
            );
        } catch (Exception $e) {
            DB::rollBack();
            $result = array(
                'code' => '300',
                'msg' => '转账失败：' . $e->getMessage(),
            );
        }
        json($result);
    }

    #[测试同步锁]
    public function lockAction()
    {
        try {
            $result = sync('mylock', function (){
                $money = 10;
                DB::beginTransaction();
                $from = memberModel::where('id', 236)->first();
                $to = memberModel::where('id', 237)->first();
                echo 'before, ', $from->money, ':', $to->money, PHP_EOL;
                if ($from->money >= $money) {
                    $from->decrement('money', $money);
                    $to->increment('money', $money);
                } else {
                    throw new Exception('积分不足');
                }
                sleep(5);
                DB::commit();
                $from = memberModel::where('id', 236)->first();
                $to = memberModel::where('id', 237)->first();
                echo 'after, ', $from->money, ':', $to->money, PHP_EOL;
                return array(
                    'code' => '200',
                    'msg' => '操作成功',
                );
            });

        } catch (Exception $e) {
            DB::rollBack();
            $result = array(
                'code' => '300',
                'msg' => '转账失败：' . $e->getMessage(),
            );
        }
        json($result);
    }

    #[提现操作日志]
    public function applylogAction()
    {
        $rows = DB::table('member_wallet_apply')->get();
        foreach ($rows as $row) {
            $rowDatas = json_decode($row->remark, true);
            foreach ($rowDatas as $rowData) {
                $event = 'apply';
                switch (true) {
                    case strstr($rowData['oper_info'], '发起'):
                        $event = 'apply';
                        break;
                    case strstr($rowData['oper_info'], '同意'):
                        $event = 'agree';
                        break;
                    case strstr($rowData['oper_info'], '拒绝'):
                        $event = 'denied';
                        break;
                    case strstr($rowData['oper_info'], '已打款'):
                        $event = 'finished';
                        break;
                }
                $data = [
                    "apply_id" => $row->id,
                    "event" => $event,
                    "event_id" => 0,
                    "oper_type" => $rowData['oper_type'],
                    "oper_id" => $rowData['oper_id'],
                    "remark" => $rowData['oper_info'],
                    "created_at" => date('Y-m-d H:i:s', $rowData["oper_time"]),
                ];
                DB::table('member_wallet_apply_log')->insert($data);
            }
        }
        echo 'Done', PHP_EOL;
    }

    #[代理商品设置]
    public function agentGoodsAction()
    {
        $allAgentGoods = agentgoodsModel::all();
        foreach ($allAgentGoods as $agentGoods) {
            if ($agentGoods->jc_rules) {
                $jc_rules = json_decode($agentGoods->jc_rules, true);
                array_push($jc_rules, ["level" => 7, "money" => "", "ratio" => ""]);
                array_push($jc_rules, ["level" => 8, "money" => "", "ratio" => ""]);
                array_push($jc_rules, ["level" => 10, "money" => "", "ratio" => ""]);
                $jc_rules_str = json_encode($jc_rules);
                $agentGoods->jc_rules = $jc_rules_str;
            }
            if ($agentGoods->pj_level1_rules) {
                $pj_level1_rules = json_decode($agentGoods->pj_level1_rules, true);
                array_push($pj_level1_rules, ["level" => 7, "money" => "", "ratio" => ""]);
                array_push($pj_level1_rules, ["level" => 8, "money" => "", "ratio" => ""]);
                array_push($pj_level1_rules, ["level" => 10, "money" => "", "ratio" => ""]);
                $pj_level1_rules_str = json_encode($pj_level1_rules);
                $agentGoods->pj_level1_rules = $pj_level1_rules_str;
            }
            if ($agentGoods->pj_level2_rules) {
                $pj_level2_rules = json_decode($agentGoods->pj_level2_rules, true);
                array_push($pj_level2_rules, ["level" => 7, "money" => "", "ratio" => ""]);
                array_push($pj_level2_rules, ["level" => 8, "money" => "", "ratio" => ""]);
                array_push($pj_level2_rules, ["level" => 10, "money" => "", "ratio" => ""]);
                $pj_level2_rules_str = json_encode($pj_level2_rules);
                $agentGoods->pj_level2_rules = $pj_level2_rules_str;
            }
            $agentGoods->save();
            echo $agentGoods->goods_id, PHP_EOL;
        }
        echo 'Done', PHP_EOL;
    }

    #[处理Excel]
    public function exportorderAction()
    {
        try {
            $file = 'C:\Users\Administrator\Desktop\双特今日订单.xlsx';
            $newfile = 'C:\Users\Administrator\Desktop\双特今日订单1.xlsx';
            $data = $this->importExcel($file, 0, 1);

            foreach ($data as $k => &$v) {
                if ($k > 1) {
                    if ($v['S'] > 0) {
                        $sendTime = json_decode($v['T'], true)['send_time'];
                        $sendTime = date('Y-m-d H:i:s', $sendTime);
                        $v['T'] = $sendTime;
                    } else {
                        $v['T'] = '';
                    }
                }
            }
            $title = [
                'ID', '订单编号', '订单类型', '支付用户ID', '代客下单ID', '收货人电话', '收货人', '省', '市', '区', '地址', '订单总价', '实际支付', '随机减', '支付方式', '数量', '商品SKU', '商品名称', '发货状态', '发货时间'
            ];
            $this->exportExcel($title, $data, $newfile);
            $result = [
                'ret' => 0,
                'msg' => '操作成功'
            ];
        } catch (Exception $e) {
            $result = [
                'ret' => 30001,
                'msg' => $e->getMessage(),
            ];
        }
        json($result);
    }

    #[处理自动收货任务队列]
    public function autoReceiveQueueAction()
    {
        $items = \orderitemModel::join('tuike_reward', 'order_item.id', '=', 'tuike_reward.order_item_id')
            ->where('tuike_reward.status', 0)
            ->where('order_item.dispatch_status', 2)
            ->where('order_item.created_at', '>', '2022-01-01')
            ->where('order_item.refund_status', 0)
            ->groupBy('order_item.id')
            ->select('order_item.*')
            ->get();

        foreach ($items as $item) {
            \Queue::push('\app\job\OrderSend@autoReceive', ['item' => $item], 'shop');
            echo $item->id, PHP_EOL;
        }
    }

    #[添加自动收货任务队列]
    public function addAutoReceiveQueueAction()
    {
        $items = orderitemModel::where('updated_at', '>', '2022-04-27')
            ->where('pay_price', '>', 0)
            ->where('refund_status', 0)
            ->where('dispatch_status', 1)
            ->where('dispatch_type', 'express')
            ->get();
        foreach ($items as $item) {
            echo $item->ext_arr['send_time'], PHP_EOL;
            if ($item->ext_arr['send_time'] > 1650988800) {
                \Queue::later(9 * 86400, '\app\job\OrderSend@autoReceive', ['item' => $item], 'shop');
                echo $item->id, '追加任务', PHP_EOL;
            }
        }
        echo 'Done', PHP_EOL;
    }

    #[四月17日前已发货订单自动收货任务队列]
    public function addHistoryAutoReceiveQueueAction()
    {
        $items = orderitemModel::where('created_at', '<', '2022-04-17 20:05:00')
            ->where('pay_price', '>', 0)
            ->where('refund_status', 0)
            ->whereIn('aftersale_status', [0, -1])
            ->where('dispatch_status', 1)
            ->get();
        foreach ($items as $item) {
            \Queue::push('\app\job\OrderSend@autoReceive', ['item' => $item], 'shop');
            echo $item->id, '追加任务', PHP_EOL;
        }
        echo 'Done', PHP_EOL;
    }

    #[手动处理分佣任务]
    public function manualsettleAction()
    {
        $orders = orderModel::where('status', '>', 0)->where('created_at', '>', '2022-03-10 00:00:00')->where('created_at', '<', '2022-4-17 20:00:00')->get();
        foreach ($orders as $order) {
            $items = orderitemModel::where('order_id', $order->id)->get();
            foreach ($items as $item) {
                echo $item->ext_arr['confirm_time'], ":", date("Y-m-d H:i:s", $item->ext_arr['confirm_time']), PHP_EOL;
                if ($item->ext_arr['confirm_time'] > 1650196800) {
                    \Hook::emit('commission_settle', ['order' => $order, 'item' => $item, 'event' => 'confirm']);
                }
            }
        }
    }

    #[手动处理指定分佣]
    public function manualsettlerewardAction()
    {
        $id = $this->get('id');
        $reward = (new \agentrewardModel)->where('id', $id)->where('status', 0)->first();
        if (!$reward) {
            throw new Exception('分佣记录不存在或已分佣完成');
        }
        $member = (new \memberModel)->where('id', $reward->agent_id)->first();
        if (!$member) {
            throw new Exception('分佣人不存在');
        }
        trace('分佣人:'. json_encode($member));

        $logRow = [
            'member_id' =>  $member->id,
            'event'     =>  $reward->class,
            'event_id'  =>  $reward->id,
            'before'    =>  $member->money,
            'money'     =>  $reward->commission,
            'after'     =>  $member->money + $reward->commission,
            'remark'    =>  '分佣到账，订单ID：'.$reward->order_id,
            'oper_type' =>  '系统',
            'oper_id'   =>  0,
            'created_at'=>  date('Y-m-d H:i:s')
        ];
        membermoneylogModel::insert($logRow);
        $member->increment('money', $reward->commission);
        $reward->status = 1;
        $reward->save();

        echo 'Done', PHP_EOL;
    }

    private function importExcel($file, $sheet = 0, $jumpTo = 2)
    {
        try {
            if (!file_exists($file)) {
                throw new \Exception('文件不存在!');
            }
            $objRead = IOFactory::createReader('Xlsx');
            if (!$objRead->canRead($file)) {
                $objRead = IOFactory::createReader('Xls');
                if (!$objRead->canRead($file)) {
                    throw new \Exception('只支持导入Excel文件！');
                }
            }
            $objRead->setReadDataOnly(true);
            $obj = $objRead->load($file);

            /* 获取指定的sheet表 */
            $currSheet = $obj->getSheet($sheet);

            if (isset($options['mergeCells'])) {
                /* 读取合并行列 */
                $options['mergeCells'] = $currSheet->getMergeCells();
            }
            /* 取得最大的列号 */
            $columnH = $currSheet->getHighestColumn();
            /* 兼容原逻辑，循环时使用的是小于等于 */
            $columnCnt = Coordinate::columnIndexFromString($columnH);

            /* 获取总行数 */
            $rowCnt = $currSheet->getHighestRow();
            $data = [];

            /* 读取内容 */
            for ($_row = $jumpTo; $_row <= $rowCnt; $_row++) {
                $isNull = true;

                for ($_column = 1; $_column <= $columnCnt; $_column++) {
                    $cellName = Coordinate::stringFromColumnIndex($_column);
                    $cellId = $cellName . $_row;
                    $cell = $currSheet->getCell($cellId);

                    if (isset($options['format'])) {
                        /* 获取格式 */
                        $format = $cell->getStyle()->getNumberFormat()->getFormatCode();
                        /* 记录格式 */
                        $options['format'][$_row][$cellName] = $format;
                    }

                    $data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue());

                    if (!empty($data[$_row][$cellName])) {
                        $isNull = false;
                    }
                }

                if ($isNull) {
                    unset($data[$_row]);
                }
            }
            return $data;
        } catch (\Exception $e) {
            dump($e->getMessage());
        }
    }

    private function exportExcel($title, $data = [], $path = '')
    {
        $spreadsheet = new PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $colcounter = count($title);
        $idx = array_key_first($data);
        $keys = $data ? array_keys($data[$idx]) : 0;

        for ($i = 1; $i <= $colcounter; $i++) {
            $sheet->setCellValue(Coordinate::stringFromColumnIndex($i) . '1', $title[$i - 1]);
        }
        $sheet->getStyle('A1:' . Coordinate::stringFromColumnIndex($i) . '1')->getFont()->setBold(true)->setColor((new Color)->setRGB('ff0000'));
        foreach ($data as $index => $row) {
            for ($j = 1; $j <= $colcounter; $j++) {
                $sheet->setCellValueExplicit(Coordinate::stringFromColumnIndex($j) . ($index + 2), $row[$keys[$j - 1]], DataType::TYPE_STRING);
            }
        }
        for ($k = 1; $k <= $colcounter; $k++) {
            $sheet->getColumnDimension(Coordinate::stringFromColumnIndex($k))->setAutoSize(true);
        }
        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
        $writer->save($path);
        $spreadsheet->disconnectWorksheets();
        unset($spreadsheet);
    }

    public function uploadCdnAction()
    {
        $cdnCfg = configModel::where('type', 4)->pluck('value', 'key');
        $accessKey = $cdnCfg['accessKey'];
        $secretKey = $cdnCfg['secretKey'];
        $bucket    = $cdnCfg['bucket'];
        // 构建鉴权对象
        $auth = new \Qiniu\Auth($accessKey, $secretKey);

        // 生成上传 Token
        $token = $auth->uploadToken($bucket);

        // 初始化 UploadManager 对象并进行文件的上传
        $uploadMgr = new \Qiniu\Storage\UploadManager;

        $attachments = attachmentModel::where('id', 1)->select('url', 'name')->get();
        foreach ($attachments as $attachment){
            // 上传到七牛后保存的文件名
            $key = $attachment->name;

            // 调用 UploadManager 的 putFile 方法进行文件的上传
            $filePath = APP_PATH.'/public/cdnfile/'.$key;
            file_put_contents($filePath, file_get_contents($attachment->url));
            list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
            if ($err !== null) {
                print_r($err);
            } else {
                echo $cdnCfg['url'] . $ret['key'], PHP_EOL;
            }
        }
        echo 'Done', PHP_EOL;
    }

    public function teamChildLineAction()
    {
        $member_id= 18854;
        $level    = 4;
        $amount   = 1;
        $levelNum = 3;
        $children = DB::table('member_children')->where('member_id', $member_id)->where('level', 1)->pluck('children_id');
        $num      = 0;
        foreach ($children as $child) {
            echo $child, PHP_EOL;
            $counter = DB::select('SELECT count(*) as cnt from cs_member where level>=:level and (id=:id or id in (SELECT children_id from cs_member_children where `member_id`=:member_id))',
                ['level'    => $level,
                 'id'       => $child,
                 'member_id'=> $child]);
            $cnt     = $counter[0]->cnt;
            if ($cnt >= $amount) {
                ++$num;
            }
            if ($num >= $levelNum) {
                break;
            }
            echo $num . PHP_EOL;
        }
        if ($num < $levelNum) {
            echo $num . 'false';
        }else{
            echo $num . 'true';
        }
        echo 'Done', PHP_EOL;
    }

    public function expressnoflushAction()
    {
        $items = orderitemModel::query()
            ->whereDate('created_at', '>=', '2022-05-20')
            ->where('express_no', '<>', '')
            ->whereNotNull('express_no')
            ->where('dispatch_status', 1)
            ->get();
        foreach ($items as $index=> $item){
            if (preg_match('/[\x{4e00}-\x{9fa5}]/u', $item->express_no)) {
                echo $index, ':', $item->express_no, 'TRUE', PHP_EOL;
                $item->dispatch_status = 0;
                $item->save();
            }else{
                echo PHP_EOL, $index, ':', $item->express_no, 'Jump', PHP_EOL, PHP_EOL;
            }
        }
    }

    public function manualpatchorderAction()
    {
        $order_sn = '202310152765891013369020';
        $order    = orderModel::query()->where('order_sn', $order_sn)->first();
        if(!$order){
            throw new Exception("订单不存在");
        }
        if($order->status>0){
            throw new Exception("订单已支付");
        }

        $notify = [
            'pay_type'          => 'patch',
            'transaction_id'    => '手动补单',
        ];
        \Hook::emit('order_payed_after', ['order' => $order, 'notify' => $notify]);
        // 预发放佣金 && 计算业绩（个人业绩 && 团队业绩 && 累计分佣） && 判断等级
        \Hook::emit('commission_init', ['order' => $order]);
    }

}
